#include<iostream>
#include<pthread.h>
#include<mutex>
#include<queue>
#include<functional>
using namespace std;
pthread_mutex_t MTX = PTHREAD_MUTEX_INITIALIZER;//用于初始化单例模式中要使用的锁
typedef function<void(int)> func_t;
void myprintf(int x)//模拟线程要执行的函数
{
    cout<<x<<" "<<endl;
}
class Task   //模拟线程要执行的任务
{
public:
    Task(func_t func = myprintf):_func(func)
    {}
public:
    func_t _func;
};
class ThreadPool
{
public:
    static ThreadPool* GetInstance()
    {
        if(_singleton == nullptr)
        {
            pthread_mutex_lock(&MTX);
            if(_singleton == nullptr)
            {
                _singleton = new ThreadPool();
                _singleton->InitThreadPool();
            }
            pthread_mutex_unlock(&MTX);
        }
        return _singleton;
    }
    void InitThreadPool()//启动线程池
    {
        for(int i=0;i<_num;i++)
        {
            pthread_t tid;
            if(pthread_create(&tid,nullptr,Routine,this)!=0)
                cout<<"线程启动失败"<<endl;
        }
        cout<<"线程池启动成功"<<endl;
    }
    static void* Routine(void* args)
    {
        ThreadPool* td = (ThreadPool*)args;
        while(1)
        {
            //拿到任务区执行
            Task t;
            pthread_mutex_lock(&td->_mtx);//加锁
            while(td->TaskQueueIsEmpty())//若资源不就绪就等待
                pthread_cond_wait(&td->_cond,&td->_mtx);
            cout<<"开始执行任务"<<endl;
            td->Pop(t);//任务队列的任务减一
            pthread_mutex_unlock(&td->_mtx);
            t._func(10);
            cout<<"一次任务执行完毕"<<endl;
        }
    }
    void Push(Task t)
    {
        pthread_mutex_lock(&_mtx);
        _q.push(t);
        pthread_mutex_unlock(&_mtx);
        pthread_cond_signal(&_cond);
        cout<<"任务push成功"<<endl;
    }
    void Pop(Task& t)
    {
        t = _q.front();
        _q.pop();
    }
    bool TaskQueueIsEmpty()
    {
        return _q.size()==0?true:false;
    }
private:
    ThreadPool(int num = 10):_num(num)
    {
        pthread_mutex_init(&_mtx,nullptr);
        pthread_cond_init(&_cond,nullptr);
    }
    ThreadPool(const ThreadPool& td) = delete;
public:
    static ThreadPool* _singleton;
    queue<Task> _q;
    int _num;//创建线程的数量
    pthread_mutex_t _mtx;
    pthread_cond_t _cond;
};
ThreadPool* ThreadPool::_singleton = nullptr;
